package blog

import (
	"context"
	"strconv"

	"github.com/gin-gonic/gin"
)

const AppName = "blogs"

type Service interface {
	// 创建文章
	CreateBlog(context.Context, *CreateBlogRequest) (*Blog, error)

	// 查询文章
	// 支持分页,关键字搜索及状态过滤
	// 管理员可以查看所有状态的文章
	// 访客只能查看已发布的文章
	QueryBlog(context.Context, *QueryBlogRequest) (*BlogSet, error)

	// 文章详情
	DescribeBlog(context.Context, *DescribeBlogRequest) (*Blog, error)

	// 修改文章
	UpdateBlog(context.Context, *UpdateBlogRequest) (*Blog, error)

	// 删除文章
	// 同时返回被删除的对象，为了兼容性
	// 比如 审计系统需要知道删除了那些对象
	// 或 要恢复删除的对象
	// 或 事件触发：事件接收方需要知道被删除的对象信息
	DeleteBlog(context.Context, *DeleteBlogRequest) (*Blog, error)
}

func NewQueryBlogRequest() *QueryBlogRequest {

	return &QueryBlogRequest{
		PageNumber: 1,
		PageSize:   20,
	}
}

func NewQueryBlogRequestFromGin(c *gin.Context) (*QueryBlogRequest, error) {
	req := NewQueryBlogRequest()
	ps := c.Query("page_size")
	pn := c.Query("page_number")
	if ps != "" {
		req.PageSize, _ = strconv.Atoi(ps)
	}
	if pn != "" {
		req.PageNumber, _ = strconv.Atoi(pn)
	}

	req.Author = c.Query("author")
	req.Keywords = c.Query("keywords")
	StatusStr := c.Query("status")
	if StatusStr != "" {
		status, err := ParseStatusFromString(StatusStr)
		if err != nil {
			return nil, err
		}
		req.Status = status
	}
	return req, nil
}

type QueryBlogRequest struct {
	// 分页大小
	PageSize int
	// 页码
	PageNumber int
	// 基于关键字参数过滤
	Keywords string
	// 基于状态过滤
	Status *Status
	// 基于作者名称过滤
	Author string
}

func (req *QueryBlogRequest) Offset() int {
	return (req.PageNumber - 1) * req.PageSize
}

func NewDescribeBlogRequest(id int) *DescribeBlogRequest {
	return &DescribeBlogRequest{
		Id: id,
	}
}

type DescribeBlogRequest struct {
	Id int
}

func NewUpdateBlogRequest(mode UpdateMode, id int, req *CreateBlogRequest) *UpdateBlogRequest {
	return &UpdateBlogRequest{
		Id:                id,
		UpdateMode:        mode,
		CreateBlogRequest: req,
	}
}

type UpdateBlogRequest struct {
	Id         int
	UpdateMode UpdateMode `jdon:"update_mode"`
	*CreateBlogRequest
}

func NewDeleteBlogRequest(id int) *DeleteBlogRequest {
	return &DeleteBlogRequest{
		Id: id,
	}
}

type DeleteBlogRequest struct {
	Id int `json:"id"`
}
